package com.seashop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.seashop.config.SystemMethodConfig;
import com.seashop.entity.*;
import com.seashop.mapper.*;
import com.seashop.service.IAdminService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seashop.util.BeanCopyUtil;
import com.seashop.util.JWTUtil;
import com.seashop.dto.AdminDTO;
import com.seashop.dto.Tree;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 运营人员表 服务实现类
 * </p>
 *
 * @author moredln
 * @since 2020-08-04
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements IAdminService {

    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private CountryMapper countryMapper;
    @Autowired
    private AdminRoleMapper adminRoleMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleResourcesMapper roleResourcesMapper;
    @Autowired
    private ResourcesMapper resourcesMapper;

    @Override
    public Map<String, Object> checkUserNameAndPassword(String username, String password) {
        Admin admin = adminMapper.selectOne(new QueryWrapper<Admin>().eq("user_name", username).eq("password", DigestUtils.md5Hex(password)).eq("is_delete", 0).eq("is_frozen", 0));
        if (null == admin) {
            return null;
        }
        AdminDTO adminDto = BeanCopyUtil.copy(admin, AdminDTO.class);
        Map<String, Object> result = new HashMap<>(2);
        result.put("token", JWTUtil.sign(admin.getUserName(), admin.getPassword()));
        result.put("admin", admin);
        String[] countryCodes = admin.getCountryCode().split(",");
        List<Country> countries = countryMapper.selectList(new QueryWrapper<Country>().in("country_code", Arrays.asList(countryCodes)));
        List<Map> list = new ArrayList<>();
        for (Country country : countries) {
            Map map = new HashMap(2);
            map.put("countryCode", country.getCountryCode());
            map.put("countryName", country.getCountryName());
            map.put("language", SystemMethodConfig.getLanguageTypeByCountryCode(country.getCountryCode()));
            list.add(map);
        }
        result.put("country", list);
        // 根据登录用户查询对应角色
        AdminRole adminRole = adminRoleMapper.selectOne(new QueryWrapper<AdminRole>().eq("admin_id", admin.getId()));
        if (adminRole == null) {
            return result;
        }
        Role role = roleMapper.selectById(adminRole.getRoleId());
        if (role == null) {
            return result;
        }
        adminDto.setRoleName(role.getRoleName());
        adminDto.setRoleId(role.getId());
        // 根据角色查询对应的资源
        List<RoleResources> roleResources = roleResourcesMapper.selectList(new QueryWrapper<RoleResources>().eq("roleid", adminRole.getRoleId()));
        if (CollectionUtils.isEmpty(roleResources)) {
            return result;
        }
        List<Integer> resourcesIds = roleResources.stream().map(RoleResources::getResourcesid).collect(Collectors.toList());
        List<Resources> resourcesList = resourcesMapper.selectBatchIds(resourcesIds);
        List<Resources> menus = new ArrayList<>();
        List<Resources> buttons = new ArrayList<>();
        if (!resourcesList.isEmpty()) {
            for (Resources resources : resourcesList) {
                if (1 == resources.getResourcesTypeCode()) {
                    menus.add(resources);
                }
                if (2 == resources.getResourcesTypeCode()) {
                    buttons.add(resources);
                }
            }
        }
        List<Tree> treeList = new ArrayList<>();
        this.parseTree(menus, treeList);
        result.put("resources", treeList);
        result.put("buttons", buttons.stream().map(Resources::getResourcesPermission).collect(Collectors.toList()));
        admin.setLastLoginTime(LocalDateTime.now());
        adminMapper.updateById(admin);
        return result;
    }

    private List<Tree> parseTree(List<Resources> resourcesList, List<Tree> treeList) {
        for (Resources resources : resourcesList) {
            if (resources.getParentId() == null) {
                Tree rootTree = new Tree();
                rootTree.setId(resources.getResourcesid());
                rootTree.setText(resources.getResourcesName());
                rootTree.setType(resources.getResourcesTypeCode());
                rootTree.setUrl(resources.getResourcesUrl());
                rootTree.setChildren(this.getChildNode(resourcesList, resources.getResourcesid()));
                rootTree.setPermission(resources.getResourcesPermission());
                rootTree.setIsHide(resources.getIsHide());
                rootTree.setFilePath(resources.getFilePath());
                treeList.add(rootTree);
            }
        }
        return treeList;
    }

    public List<Tree> getChildNode(List<Resources> list, Long parentId) {
        List<Tree> result = new ArrayList<>();
        for (Resources resources : list) {
            if (parentId.equals(resources.getParentId())) {
                Tree tree = new Tree();
                tree.setId(resources.getResourcesid());
                tree.setParentId(parentId);
                tree.setUrl(resources.getResourcesUrl());
                tree.setText(resources.getResourcesName());
                tree.setType(resources.getResourcesTypeCode());
                tree.setChildren(getChildNode(list, resources.getResourcesid()));
                tree.setPermission(resources.getResourcesPermission());
                tree.setIsHide(resources.getIsHide());
                tree.setFilePath(resources.getFilePath());
                result.add(tree);
            }
        }
        return result;
    }
}
